package org.springframework.boot.netty.view;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.boot.autoconfigure.netty.NettyProperties;
import org.springframework.boot.netty.support.ModelAndView;
import org.springframework.boot.netty.support.TemplateWriter;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;


import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;


/**
 * Author: huoxingzhi
 * Date: 2020/12/28
 * Email: hxz_798561819@163.com
 */
public class ThymeleafView implements View,SmartInitializingSingleton {

    private NettyProperties nettyProperties;

    private ClassLoaderTemplateResolver templateResolver = null;

    private TemplateEngine templateEngine = null;

    public ThymeleafView() {
    }


    public ThymeleafView(NettyProperties nettyProperties) {
        this.nettyProperties = nettyProperties;
    }

    @Override
    public void render(io.netty.channel.Channel channel, ModelAndView modelAndView) throws Exception {

        FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK);
        Context context = new Context();
        context.setVariables(modelAndView.getModel());
        TemplateWriter writer = new TemplateWriter();
        //Executing template engine
        templateEngine.process(String.valueOf(modelAndView.getView()), context, writer);

        String body = writer.getBody();
        ByteBuf buffer = Unpooled.copiedBuffer(body.getBytes("UTF-8"));
        response.content().writeBytes(buffer);

        response.headers().set(HttpHeaderNames.CONTENT_TYPE, HTML);
        // 需要渲染,不缓存
        response.headers().set(HttpHeaderNames.EXPIRES, "Thu, 01-Jan-1970 00:00:00 GMT");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
        response.headers().set(HttpHeaderNames.SERVER, SERVER);

        buffer.release();
        channel.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);

    }




    @Override
    public void afterSingletonsInstantiated() {
        templateResolver = new ClassLoaderTemplateResolver();
        // XHTML is the default mode, but we will set it anyway for better understanding of code
        templateResolver.setTemplateMode(TemplateMode.HTML);

        // This will convert "home" to "/WEB-INF/templates/home.html"
        templateResolver.setPrefix(this.nettyProperties.getViewPrefix());
        templateResolver.setSuffix(".html");
        // Set template cache TTL to 1 hour. If not set, entries would live in cache until expelled by LRU
        templateResolver.setCacheTTLMs(Long.valueOf(3600000L));
        // Cache is set to true by default. Set to false if you want templates to
        // be automatically updated when modified.
        templateResolver.setCacheable(true);
        //Create Template Engine
        templateEngine = new TemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);

    }


}
